from utils import *

def postflopBot(player):
    # player.postflopAggro, postflopTight, absHS, adjHS1, adjHS2, draws, Pot.size, pot.toCall(Player)

    if player.position == 1 or (player.position == 2 and player.rightOpp.folded):
        (aggression, tightness) = (.9 * player.postflopAggro, .9 * player.postflopTight)
    else:
        if Pot.toCall(player) == 0:
            (aggression, tightness) = (1.2 * player.postflopAggro, 1.1 * player.postflopTight)
        else:
            (aggression, tightness) = (.7 * player.postflopAggro, 1.1 * player.postflopTight)
            player.bigBet *= 1.3
    raiseIndex = max(1 - player.adjHS1, 0)**.9 * max(1 - player.adjHS2, 0)**.9 + .3 * player.draws + .13
    callIndex =  max(.90 - player.adjHS1, 0) * max(.90 - player.adjHS2, 0) + .5 * player.draws - .03
    if Game.playersLeft == 2:
        callIndex += .05
    if callIndex < .05:
        callIndex = .05
    if player.absHS < .06:
        callIndex = 1
    raiseChance = postflopRaise(player, raiseIndex, aggression)
    if player.absHS < .15 and player.draws < .05:
        raiseChance *= 1.1
    elif player.absHS < .3 and player.draws < .05:
        raiseChance *= 1.05
    if Pot.size > 35:
        raiseChance *= 1.2
    callUpTo = (1 - callIndex) / callIndex * (tightness / MY_POSTFLOP_TIGHT)
    x = random.random()
    if x < raiseChance:
        raiseAmt = (.3 * raiseChance + .1 * (x - raiseChance * .5)) * player.bigBet / .5
    else:
        raiseAmt = 0
    if raiseIndex > .7:
        raiseAmt *= (raiseIndex + .45)
    return (raiseAmt, callUpTo)

def postflopRaise(player, raiseIndex, aggression):
    if Game.street == 3:
        player.slowplay = 0
    if raiseIndex > .8:
        return 1 - player.slowplay
    elif raiseIndex + aggression > 1:
        return min(1 - player.slowplay, raiseIndex)
    elif raiseIndex + aggression > .8:
        return max(player.bluff, .75 * raiseIndex)
    return player.bluff

def strategize(player):
    # char = (aggro, tight, slowplay, bluff, winPct, foldedPct)
    char1 = [player.leftOpp.postflopAggro, player.leftOpp.postflopTight, player.leftOpp.slowplay, player.leftOpp.bluff, player.leftOpp.winPct, player.leftOpp.foldedPct]
    char2 = [player.rightOpp.postflopAggro, player.rightOpp.postflopTight, player.rightOpp.slowplay, player.rightOpp.bluff, player.rightOpp.winPct, player.rightOpp.foldedPct]
    if player.leftOpp.folded:
        char = char2
    elif player.rightOpp.folded:
        char = char1
    else:
        char = [(i[0] + i[1]) / 2. for i in zip(char1, char2)]
#    oppAggro = max(char[0] - .2 * (char[2] - .2) + .4 * (char[3] - .2), 0)
#    oppTight = min(char[1] + .4 * (char[3] - .2), 1)
    if Game.handId > 30:
        oppTight = .5 * (char[1] + 1 - .8 * char[5])
        oppAggro = .3 * char[4] + .7 * char[0]
    else:
        oppTight = OPP_POSTFLOP_TIGHT
        oppAggro = OPP_POSTFLOP_AGGRO
    player.slowplay = checkSlowplay(MY_SLOWPLAY + .5 * (oppAggro - OPP_POSTFLOP_AGGRO))
    player.bluff = checkBluff(MY_BLUFF - .7 * (oppTight - OPP_POSTFLOP_TIGHT))
    if Game.handId > 60:
        player.postflopAggro = checkAggro(MY_POSTFLOP_AGGRO + .5 * (char[5] - .5))
        player.postflopTight = checkTight(MY_POSTFLOP_TIGHT + (oppAggro - OPP_POSTFLOP_AGGRO) + 1.3 * (oppTight - .6))
        player.bigBet = checkBigBet(MY_BIG_BET + 1.2 * (oppTight - OPP_POSTFLOP_TIGHT))
    elif Game.handId > 25:
        player.postflopAggro = checkAggro(MY_POSTFLOP_AGGRO + .3 * (char[5] - .5))
        player.postflopTight = checkTight(MY_POSTFLOP_TIGHT + .4 * (oppAggro - OPP_POSTFLOP_AGGRO + oppTight - .6))
        player.bigBet = checkBigBet(MY_BIG_BET + .5 * (oppTight - OPP_POSTFLOP_TIGHT))

def checkSlowplay(slowplay):
    if slowplay < MY_SLOWPLAY - .05:
        return MY_SLOWPLAY - .05
    if slowplay > MY_SLOWPLAY + .15:
        return MY_SLOWPLAY + .15
    return slowplay
        
def checkBluff(bluff):
    if bluff < MY_BLUFF - .1:
        return MY_BLUFF  - .1
    if bluff > MY_BLUFF + .15:
        return MY_BLUFF + .15
    return bluff
        
def checkAggro(aggro):
    if aggro < MY_POSTFLOP_AGGRO - .15:
        return MY_POSTFLOP_AGGRO - .15
    if aggro > MY_POSTFLOP_AGGRO + .15:
        return MY_POSTFLOP_AGGRO + .15
    return aggro
    
def checkTight(tight):
    if tight < MY_POSTFLOP_TIGHT - .15:
        return MY_POSTFLOP_TIGHT - .15
    if tight > MY_POSTFLOP_TIGHT + .15:
        return MY_POSTFLOP_TIGHT + .15
    return tight
    
def checkBigBet(bigBet):
    if bigBet < MY_BIG_BET - .15:
        return MY_BIG_BET - .15
    if bigBet > MY_BIG_BET + .15:
        return MY_BIG_BET + .15
    return bigBet

def postflopStrength(hand, community, street):
    unknowns = 2
    pockets = [[card.id for card in hand.cards], [255, 255]]
    board = [card.id for card in community.cards]
    unknowns += 5 - len(board)
    board = board + [255] * (5 - len(board))
    strength = parseEval(pokereval.poker_eval('holdem', pockets, board, iterations = 30000))
    if street == 1:
        strength = flopScaleWin(strength)
    elif street == 2:
        strength = turnScaleWin(strength)
    elif street == 3:
        strength = 1 - strength / 1000.
    return strength
